/**
**************************************************************************************
*Founder Effect                                                                      *
*Copyright (C) 2006-2007, 5d Studios (www.5d-Studios.com)                            *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#include "StdAfx.h"
#include "ConsoleView.h"
#include "../kernel.h"
#include "irender.h"

extern Kernel* g_kernel;

#define CONSOLE_DEPTH 600
#define TIME (g_kernel->GetTime())

ConsoleView::ConsoleView(Console* c)
{
    m_console = c;
    m_upTrack  = false;
    m_tick = true;
    m_time = 0.0L;
}

/** Render the console */
void ConsoleView::Render( IRender *r, ICamera* cam  )
{
    console_t* cons = m_console->GetDisplay();
    if ( CheckMove( cons ) )
    {
        int height = g_kernel->GetCvars()->GetFloatValue("v_height") * cons->m_fraction;
        int depth = height - 100;
        RenderBackground( r, cam, depth, height );
        RenderCursor( r, cam, depth );
        RenderText( r, cam, depth, cons->m_display, cons->m_printStack );    
    }
}

/** Display moving */
bool ConsoleView::CheckMove( console_t* cons )
{
    // dont waste time listening for input
    if ( !m_console->IsShowing() ) {
        // close the console
        if ( cons->m_moving ) {
            cons->m_fraction -= 0.02f;
            if ( cons->m_fraction < 0.0 ) 
            {
                cons->m_fraction = 0.0f;
                cons->m_moving = false; 
            }
        }
        return true;
    }
    // open the console
    if ( cons->m_moving ) {
        cons->m_fraction += 0.02f;
        if ( cons->m_fraction > 0.5 ) 
        {
            cons->m_fraction = 0.5f;
            cons->m_moving = false;
        }
    }
    if ( !cons->m_fraction )
        return false;
    return true;
}

/** Draw cursor */
void ConsoleView::RenderCursor( IRender* r, ICamera* cam, int depth )
{
    InputBuffer* buffer = m_console->GetBuffer();
    r->SetColor(0.0f,0.0f,0.0f,1);
    r->DrawString(10, depth - 20, (">" + buffer->GetBuffer()).c_str() ); 

    // make a cursor
    if ( m_tick ) {
        int index = 0;
        // TODO - Make the cursor in proper position
        for ( int i = 0; i < buffer->GetCarrotPos(); i++ )
            index += r->GetTextWidth( buffer->GetBuffer()[i] );
        r->DrawString( 20 + index/*8*buffer->GetCarrotPos()*/, depth - 20, "|");
        
    }
    // blicking cursor
    if ( m_time < TIME ) 
    {
        m_tick = !m_tick;
        m_time = TIME + 500; // blink every half sec
    }
}

/** Render Background */
void ConsoleView::RenderBackground( IRender* r, ICamera* cam, int depth, int height )
{
    // Get the width of the app
    int width  = g_kernel->GetCvars()->GetFloatValue("v_width");

    r->SetColor(0.70f, 0.92f, 0.30f, .40f); // TODO: Make this a variable bg color
    // Create the backtile
    r->DrawRect(0, 0, width, depth );
    r->FillRect(0, 0, width, depth ); // 400

    r->SetColor(0.1f,0.1f,0.1f,1);
    r->DrawRect(0, depth-20, width, 2 ); // 420
}

/** Render Text */
void ConsoleView::RenderText( IRender* r, ICamera* cam, int depth, int displayHeight, std::list<std::string> &stack  )
{
    m_upTrack = false;

    int y = 0, i = 0; 
    std::list<std::string>::reverse_iterator it;
    for( it = stack.rbegin() ; it != stack.rend(); ++it, ++i )
    {
            y = displayHeight - (i * r->GetTextHeight('H')); 
            if ( y <= 15 ) {             
                continue;
            }
			// Indicate that there is text above
            if ( y >= depth - 40 ) {
                m_upTrack = true;
                continue;
            }
           
            r->DrawString(10, y, (">" + (*it)).c_str()  );
    }

    if ( m_upTrack ) 
        r->DrawString( 10, depth - 30, "^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^" );
    
}

ConsoleView::~ConsoleView(void)
{
}
